import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
%matplotlib inline
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
from pandas.plotting import register_matplotlib_converters
import warnings
import plotly.graph_objects as go
import plotly.express as px
import plotly.offline as offline
fig = go.Figure(data=[go.Bar(y=[2, 3, 1])])
offline.plot(fig, filename='my_plot.html')
import json
import requests
from folium import Map, Choropleth, Marker, Icon
from folium.plugins import MarkerCluster
import folium
from plotly.subplots import make_subplots
from folium import Map, Choropleth
from branca.colormap import LinearColormap
from folium import plugins
df = pd.read_csv('/datasets/moscow_places.csv')
df
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | WoWфли | кафе | Москва, улица Дыбенко, 7/1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.878494 | 37.478860 | 5.0 | NaN | NaN | NaN | NaN | 0 | NaN |
| 1 | Четыре комнаты | ресторан | Москва, улица Дыбенко, 36, корп. 1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.875801 | 37.484479 | 4.5 | выше среднего | Средний счёт:1500–1600 ₽ | 1550.0 | NaN | 0 | 4.0 |
| 2 | Хазри | кафе | Москва, Клязьминская улица, 15 | Северный административный округ | пн-чт 11:00–02:00; пт,сб 11:00–05:00; вс 11:00... | 55.889146 | 37.525901 | 4.6 | средние | Средний счёт:от 1000 ₽ | 1000.0 | NaN | 0 | 45.0 |
| 3 | Dormouse Coffee Shop | кофейня | Москва, улица Маршала Федоренко, 12 | Северный административный округ | ежедневно, 09:00–22:00 | 55.881608 | 37.488860 | 5.0 | NaN | Цена чашки капучино:155–185 ₽ | NaN | 170.0 | 0 | NaN |
| 4 | Иль Марко | пиццерия | Москва, Правобережная улица, 1Б | Северный административный округ | ежедневно, 10:00–22:00 | 55.881166 | 37.449357 | 5.0 | средние | Средний счёт:400–600 ₽ | 500.0 | NaN | 1 | 148.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8401 | Суши Мания | кафе | Москва, Профсоюзная улица, 56 | Юго-Западный административный округ | ежедневно, 09:00–02:00 | 55.670021 | 37.552480 | 4.4 | NaN | NaN | NaN | NaN | 0 | 86.0 |
| 8402 | Миславнес | кафе | Москва, Пролетарский проспект, 19, корп. 1 | Южный административный округ | ежедневно, 08:00–22:00 | 55.640875 | 37.656553 | 4.8 | NaN | NaN | NaN | NaN | 0 | 150.0 |
| 8403 | Самовар | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648859 | 37.743219 | 3.9 | NaN | Средний счёт:от 150 ₽ | 150.0 | NaN | 0 | 150.0 |
| 8404 | Чайхана Sabr | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648849 | 37.743222 | 4.2 | NaN | NaN | NaN | NaN | 1 | 150.0 |
| 8405 | Kebab Time | кафе | Москва, Россошанский проезд, 6 | Южный административный округ | ежедневно, круглосуточно | 55.598229 | 37.604702 | 3.9 | NaN | NaN | NaN | NaN | 0 | 12.0 |
8406 rows × 14 columns
print('Количество заведений:', df['name'].nunique())
Количество заведений: 5614
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 8406 entries, 0 to 8405 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 8406 non-null object 1 category 8406 non-null object 2 address 8406 non-null object 3 district 8406 non-null object 4 hours 7870 non-null object 5 lat 8406 non-null float64 6 lng 8406 non-null float64 7 rating 8406 non-null float64 8 price 3315 non-null object 9 avg_bill 3816 non-null object 10 middle_avg_bill 3149 non-null float64 11 middle_coffee_cup 535 non-null float64 12 chain 8406 non-null int64 13 seats 4795 non-null float64 dtypes: float64(6), int64(1), object(7) memory usage: 919.5+ KB
df.describe()
| lat | lng | rating | middle_avg_bill | middle_coffee_cup | chain | seats | |
|---|---|---|---|---|---|---|---|
| count | 8406.000000 | 8406.000000 | 8406.000000 | 3149.000000 | 535.000000 | 8406.000000 | 4795.000000 |
| mean | 55.750109 | 37.608570 | 4.229895 | 958.053668 | 174.721495 | 0.381275 | 108.421689 |
| std | 0.069658 | 0.098597 | 0.470348 | 1009.732845 | 88.951103 | 0.485729 | 122.833396 |
| min | 55.573942 | 37.355651 | 1.000000 | 0.000000 | 60.000000 | 0.000000 | 0.000000 |
| 25% | 55.705155 | 37.538583 | 4.100000 | 375.000000 | 124.500000 | 0.000000 | 40.000000 |
| 50% | 55.753425 | 37.605246 | 4.300000 | 750.000000 | 169.000000 | 0.000000 | 75.000000 |
| 75% | 55.795041 | 37.664792 | 4.400000 | 1250.000000 | 225.000000 | 1.000000 | 140.000000 |
| max | 55.928943 | 37.874466 | 5.000000 | 35000.000000 | 1568.000000 | 1.000000 | 1288.000000 |
Комментарий:
Всего представлено 5614 уникальных заведений. На первый взгяд много пропусков. Можно посчитать долю пустых значений этих столбцов для наглядности. Есть довольно высокая оценка среднего чека - 35000, также максимальное колиество посадочных мест - 1288 (это очень много). Тип столбца seats 64-битное число с плавающей запятой, что некорректно.
df.groupby('seats')['name'].max()
seats
0.0 Японская кухня
1.0 Шаурма
2.0 Японские традиции
3.0 Юнус Халяль
4.0 Шаурму Х@чу
...
760.0 Дом
920.0 Стейк & Бургер
1040.0 Шоколадница
1200.0 РестоБар Argomento
1288.0 Японская кухня
Name: name, Length: 229, dtype: object
Огромное количество посадочных мест в заведении 'японская кухня'. Непохоже на название, возможно стоит удалить такие места, чтобы не исказить данные выбросами.
df.groupby('name')['seats'].count().sort_values(ascending=False)
name
Шоколадница 83
Кафе 74
Додо Пицца 62
Домино'с Пицца 61
One Price Coffee 52
..
Маренго 0
Royal hookah 0
Romashoff 0
Roma Pizza Coffee 0
#КешбэкКафе 0
Name: seats, Length: 5614, dtype: int64
df['seats'].max()
1288.0
df.loc[df['seats'] > 500, 'seats'].count()
56
df.groupby(by='category', as_index=False).agg(
min=('seats', 'min'),
max=('seats', 'max'),
mean=('seats', 'mean'),
median=('seats', 'median'))
| category | min | max | mean | median | |
|---|---|---|---|---|---|
| 0 | бар,паб | 0.0 | 1288.0 | 124.532051 | 82.5 |
| 1 | булочная | 0.0 | 625.0 | 89.385135 | 50.0 |
| 2 | быстрое питание | 0.0 | 1040.0 | 98.891117 | 65.0 |
| 3 | кафе | 0.0 | 1288.0 | 97.512315 | 60.0 |
| 4 | кофейня | 0.0 | 1288.0 | 111.199734 | 80.0 |
| 5 | пиццерия | 0.0 | 1288.0 | 94.496487 | 55.0 |
| 6 | ресторан | 0.0 | 1288.0 | 121.944094 | 86.0 |
| 7 | столовая | 0.0 | 1200.0 | 99.750000 | 75.5 |
def seats_category(seats):
if (seats != seats):
return np.nan
seats = int(seats)
if (seats == 0):
return '0'
elif (seats <= 25):
return 'Очень малые (1 - 25)'
elif (seats <= 50):
return 'Малые (26 - 50)'
elif (seats <= 100):
return 'Средние (51 - 100)'
elif (seats <= 250):
return 'Крупные (101 - 250)'
elif (seats <= 500):
return 'Очень крупные (251 - 500)'
else:
return 'Аномальные (501 +)'
df['seats_category'] = df['seats'].apply(seats_category)
category_and_seats=df.groupby(['category', 'seats_category'], as_index=False).agg(count=('category', 'count')).sort_values('count', ascending=False)
fig = px.bar(
category_and_seats,
x='category',
y='count',
title='Распределение заведений по категориям посадочных мест',
color='seats_category')
fig.update_layout(
xaxis_title='Категория заведения',
yaxis_title='Количество заведений',
xaxis_tickangle=-45,
xaxis={'categoryorder':'total descending'}
)
fig.show()
Комментарий:
print('Дубликатов:', df.duplicated().sum())
Дубликатов: 0
Явных дубликатов нет, посмотрим неявные. Наверняка заведений с одинаковым названием, улицей и районом нет.
df['name'] = df['name'].str.lower()
df[df.duplicated(subset = ['name', 'address', 'district'], keep=False)]
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | seats_category | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1430 | more poke | ресторан | Москва, Волоколамское шоссе, 11, стр. 2 | Северный административный округ | ежедневно, 09:00–21:00 | 55.806307 | 37.497566 | 4.2 | NaN | NaN | NaN | NaN | 0 | 188.0 | Крупные (101 - 250) |
| 1511 | more poke | ресторан | Москва, Волоколамское шоссе, 11, стр. 2 | Северный административный округ | пн-чт 09:00–18:00; пт,сб 09:00–21:00; вс 09:00... | 55.806307 | 37.497566 | 4.2 | NaN | NaN | NaN | NaN | 1 | 188.0 | Крупные (101 - 250) |
| 2211 | раковарня клешни и хвосты | ресторан | Москва, проспект Мира, 118 | Северо-Восточный административный округ | ежедневно, 12:00–00:00 | 55.810553 | 37.638161 | 4.4 | NaN | NaN | NaN | NaN | 0 | 150.0 | Крупные (101 - 250) |
| 2420 | раковарня клешни и хвосты | бар,паб | Москва, проспект Мира, 118 | Северо-Восточный административный округ | пн-чт 12:00–00:00; пт,сб 12:00–01:00; вс 12:00... | 55.810677 | 37.638379 | 4.4 | NaN | NaN | NaN | NaN | 1 | 150.0 | Крупные (101 - 250) |
| 3091 | хлеб да выпечка | булочная | Москва, Ярцевская улица, 19 | Западный административный округ | ежедневно, 09:00–22:00 | 55.738886 | 37.411648 | 4.1 | NaN | NaN | NaN | NaN | 1 | 276.0 | Очень крупные (251 - 500) |
| 3109 | хлеб да выпечка | кафе | Москва, Ярцевская улица, 19 | Западный административный округ | NaN | 55.738449 | 37.410937 | 4.1 | NaN | NaN | NaN | NaN | 0 | 276.0 | Очень крупные (251 - 500) |
3 совпадения, удалим их.
df.drop_duplicates(subset=['name', 'address', 'district'], keep='first', inplace=True)
df.duplicated(subset = ['name', 'address', 'district']).sum()
0
df['name'].to_list()
['wowфли', 'четыре комнаты', 'хазри', 'dormouse coffee shop', 'иль марко', 'sergio pizza', 'огни города', 'mr. уголёк', 'donna maria', 'готика', 'great room bar', 'шашлык шефф', 'заправка', 'буханка', 'у сильвы', 'дом обеда', 'база стритфуд', 'чайхана беш-бармак', 'час-пик', 'пекарня', 'чебуреки манты', '7/12', 'крымские чебуреки', 'буханка', 'drive café', 'в парке вкуснее', 'пикочино', 'шаурму х@чу', 'mafe', 'кушай город', 'кафедра', 'алталия', 'додо пицца', 'изба', "домино'с пицца", 'виладж пицца', 'пекарня № 1 грузинская кухня', 'халяль закусочная', 'ижора', 'шаурмагия', 'кафе', 'крошка картошка', 'варня кафе', 'суши & пицца', 'кафетерий', '9 bar coffee', 'cofefest', 'кафе', 'блинбери', '2u-ту-ю', 'шаурма', 'арамье', 'cofix', 'royal coffee', 'шашлык', 'чебуреки и манты', 'рыба из тандыра', 'мир пиццы', "coffeekaldi's", 'хинкали gали!', 'чебуречная история', 'кафе лоза', 'пить есть!', 'pizza hut', 'testo мания', 'альбатрос', 'молинари', 'штаб квартира', 'мимино', 'алазанская долина', 'гуава бар', 'cofefest', 'лакрица', 'веранда', 'хинкали-gали!', 'хинкали-gали!', 'ресторан купец', 'оазис', 'ресторан самарканд', 'ресторан landau cafe & grill bar', 'му-му', 'coffee way', 'пиросмани', 'аль-бухари', 'meat doner kebab', 'дежене', 'халяль', 'гриль хаус', 'zамания', 'сахарочек', 'кафе на пришвина', 'шашлык', 'лавашок', 'jamamai asian kitchen & bar', "домино'с пицца", 'додо пицца', 'cofefest', 'жигулевское', 'тбилисоба', 'чайхана омад', 'take and wake', 'шаурмовик', 'мята signature алтуфьево', 'тетри', 'pho street', 'star hit cafe', 'вектор', 'теремок', 'кафе', 'чайхана', 'ocean лав', 'алазани', 'pho ханой', 'bowl family', 'островок суши', 'сеть поминальных залов', 'алло! пицца', 'ретро нью', 'cofefest', 'додо пицца', 'два бобра', 'встреча', 'жарим мясо', 'кафе', 'шашлык хаус', 'лотос', 'кулинария', 'арарат', 'калина', 'pizza sole', 'meatлав', 'crosseat', 'пекарня-шаурма', 'крепери', 'van house', 'чудо печка', 'ho chu pho', 'get and fly', 'хинкальная', 'шеф бургер', 'парус', 'кафе', 'кулинария', 'one price coffee', 'art coffee club', 'пеликан', 'скалка', 'кофетун-сушитун', 'халяль', 'коффе души', 'правда', 'шоколадница', 'все шашлыки', 'магбургер', 'бистро 24', 'поляна', 'бобры', 'линии вкуса', 'палки-скалки', 'кафе', 'лакафе', "домино'с пицца", 'яндекс лавка', 'wild bean cafe', 'эстетик', 'флокс', 'бута бар', 'узбекистан', 'шаурма на углях', "домино'с пицца", 'кафе луна', 'one price coffee', 'menza', 'булкер', 'домовёнок кузя', 'ресторан', 'вуди пицца', 'арамье', 'кушай город', 'буханка', 'fresita pizza', 'fire', 'карелия', 'кафе', 'мосплов', 'донер кебаб', 'фри фло бар', 'cofefest', 'сушистор', 'кафе', 'кафе', 'кулинарный дворик 1996', 'шаурма', 'яндекс лавка', 'ленкорань', 'sushi city', 'донер-шашлык', 'ош', 'толстяк', 'мастер вкуса', 'wild bean', 'восточная кухня', 'i-coffee. me', 'тандыр № 1', 'пицца фалафилло халяль', 'еда greek', 'vintage', 'mr. пи', 'чайхана', 'кафе', 'центр вкуса', 'неаполитан пицца', 'яндекс лавка', 'семьяне', 'family cafe', 'кафе', 'грузинский бульвар', '16 июня', 'джари', 'бистро хинкальная', 'тбилисо', 'глобус ресторан', 'андерсон', 'the zavtrak', 'обжора', 'rozie bakery', 'чайхана ташкент', 'ла гатта', 'мск lounge', 'свои люди', 'мегаполис кафе', 'dolce & gamarjoba', 'полярная звезда', 'шашлычный дворик', 'chicken father', 'аршин', 'maппа', 'империал', 'причина для капучино', 'уголёк', 'шоколадница', 'алиби', 'греческая кухня', 'хлеб с маслом', 'ресторан дежа вю', 'буханка', 'самса хаус', 'тайна', 'антик', 'шаурма и бургер', 'ани', 'еда greek', 'сеть кафе зарядка', 'чайхана найман', 'ай эм конфидент', 'чайхана самарканд', 'додо пицца', 'x-ti гастробар', 'буханка', 'чайхана москва-ташкент', 'кулинария', 'кафетерий при азк 317', 'doner & tantuni', 'доминос пицца', 'акбаш', 'пицца 28 сантиметров', 'пекарня&донер', 'кафе-кофе', 'тандыр № 1', 'скалка', 'guru', 'алали', 'крошка картошка', 'pho oanh', 'чайхана', 'додо пицца', 'mr. колобокок', "pho' mos", 'muine', 'сладкие минуты', 'кофе-сэндвичи', 'донер и выпечка', 'светлана', 'рестоль', 'центр плов', 'пицца', 'шашлычный дворик', 'royal hookah', 'ресторан', 'пеко', 'шаурма', 'мясная кулинария', 'волга-волга', 'parkhouse', 'kurnik', 'мерси баку', 'аморино', 'ла гатта', 'чайхана ором +24', 'калитки', "ресторан стейк's", 'лавлаваш', 'легенда', 'signora', 'forest lounge', 'mansard restaurant and hall', 'everest coffee', 'грузинский дом у наны', 'старые друзья', 'легенда самарканда', 'vasilchukí chaihona №1', 'тануки', 'рандеву', 'zotto', 'сундук', 'ярмарка морских блюд', 'груша', 'vоdный', 'дружба', 'мархал', 'паб-ресторан cuba', 'hatimaki', 'хинкали-gали!', 'джонджоли', 'иду лесом', 'pho city', 'барkas', 'hatimaki', 'у михалыча', 'скалка', 'sushiball', 'юг', 'тони пиццони', 'viet ngon', 'бургер х@чу', 'molto bello', 'нугбари', 'пекарня маковка', 'чайхона айва', 'чайхона № 1', 'vasilchukí chaihona №1', 'чайхана баракат', 'эрмитаж', 'шоколадница', 'coffee moose', 'кофе тема', 'пилпили', "coffeebar'17", 'meat лав', 'трактир на лодочной', 'гран торино пицца', 'маковка', 'tropic coffee', 'нэм нэм', 'стар самарканд', 'княжий дворик', 'мархал', 'братья гримм', 'уголок', 'кофе с собой кофемол', 'шоколадница', 'моспончики', 'му-му', 'ла гатта', 'кондитерская олега ильина', 'гранд', 'гемри&эли хинкальная', 'мосшашлык', 'мск lounge', 'горячая выпечка', 'viet ngon', 'мир шашлыков', 'ыссык-кол', 'виват пицца', 'вельвет', 'сходненская56', 'чебуреки манты', 'пивной ресторан пив&ко', 'кафе-пекарня', 'самарканд', 'чайхана 24', 'шоколадница', 'halal food', 'french bakery', 'drive café', 'o.k. coffee', 'ngon', 'чайхана кумыс', 'via pомано', 'sport club g5+', 'премьер пицца', 'корнели пицца', 'кеклик', 'гурман-кафе', 'чайхана', 'спорт кафе', 'франклинс бургер', 'плов центр', 'легенда', 'самарканд', 'mr. brown', 'аморет', 'серебряная ложка', 'дон тантуни', 'шашлыкофф', 'bierлога', 'шаурма мир вокруг', 'паровозик', 'кофейня свежий номер', 'кафе-бар улыбка', 'огни востока', 'кетчуп & горчица', 'тбилисоба', 'парус', 'mr. ambar', 'юма', 'чайхана халал', 'сибирская корона', 'эллилагер', 'cofix', 'профессоре', 'кружка паб', "coffeebar'17", 'удача', 'паб 28/13', 'кафе court', 'грузинка', 'вкинобар', 'кружка паб', 'мята lounge', '10 идеальных пицц', 'сакура', 'додо пицца', 'little panda cafe', 'кафе 11/11', 'pizza express 24', 'one price coffee', 'буханка', 'кафе бригантина', 'лаззат', 'хлеб хаус', 'халяльная еда', 'регар сити', 'нияма', 'coffee and the city', 'кофе твой друг', 'домашний вкус', 'ели шашлык', 'pizza express 24', 'чудо тандыр', 'чайхана халаль', 'drive café', 'мясо&паста', 'sedelice', 'алло! пицца', 'шоколадница', 'one price coffee', 'drive café', 'one price coffee', 'теремок', 'адажио', 'чайхана хизмат', 'додо пицца', 'мерлин', 'чайхана райан', 'бота', 'шах-даг', 'мэри групп', 'foodkido', 'библиотека путешествий', 'pizza mafia', 'додо пицца', 'кафе-клуб сказка', 'коп-team', 'сушистор', 'korean chick', "домино'с пицца", 'cofix', 'чайхона', 'гурмэ ланч', 'грузинская лавка', 'pastas & tapas', 'ресторан вьетнамской кухни бик-кау', 'шоколадница', 'фастфуд', "домино'с пицца", 'додо пицца', 'кафе-столовая', 'магазин шашлыка № 1', 'cofix', 'бик кау', 'арамье', 'cinnabon', "домино'с пицца", 'старая арба', 'one price coffee', 'чайхана регар', 'самарканд', 'донер кебаб', 'столовая', 'кафешка', 'vua pho', 'кафе чудо', 'додо пицца', 'буше на свободе', 'хинкарули', 'виктория', 'кафе', 'алаверды', 'шаурма', 'шеff накормит', 'долина вкуса', 'шоколадница', 'долина № 1', 'донер кебаб', 'столовая', 'coffee break', 'шашлычная-шашлындос', 'cofix', 'шаурма', 'vse-em', 'рандеву', 'буханка', 'cofix', 'коксинель', 'огонек', 'живое пиво', 'ресторан', 'workout bar', 'шоколадница', 'шашлычная', 'arzon food', 'хлебный двор', 'кафе', 'узбечка', 'пекарня', 'cafeterius simple', 'кафе', 'pho hanoi', 'french bakery', 'city life', 'пляж-ресторан речной', 'coffee guru', 'столовая', 'крошка картошка', 'додо пицца', 'que me', "домино'с пицца", 'кофепорт', 'pho 73', 'гастро бистро шаверма-братуха', 'кофе с собой а&m', 'кафе', 'донер тандыр', 'пекарня 24', 'styling bull cafe', 'sushi-das.ru', 'луна', 'добродомик офис', 'one price coffee', 'pizzaloca', 'стейки good prime', 'мир плова и шашлыка', '69 раков', 'кафе бар', 'boulangerie', 'ресторан', 'dimsum & co', 'буханка', 'фрешка', 'new sushi', 'чемпион', 'шаурмангал', 'ковчег', 'пекарня', 'скалка', 'espresso patronum', 'чай хана халал', 'шашлычков', 'arzon', 'caffa', 'шаурма 24 гриль', 'кафе', 'донер хаус', 'кафе', 'кафе', 'столовая', "домино'с пицца", 'фо тхин. phở thìn', 'чайхана элина', 'донерок', 'ann joy', 'нтс', 'кафе', 'вояж', 'трдельнишная', 'кафе регистон', 'поминальные обеды', 'кафе-столовая', 'в парке вкуснее!', 'в парке вкуснее', 'аль баракат', 'кафе', 'чайная', 'кулинария на сходненской', 'cinnabon', 'top java', 'captain gyros', 'coffprice', 'city life', 'напитки со всего мира', 'бота', "домино'с пицца", 'wаурма', 'кафе', 'julibon cafe', 'zeкафетерия', 'дом пива', 'черепашка', 'fruitsberry', 'избёнка', 'узбекская национальная кухня', 'шаурма на районе № 1', 'solotreid', 'соседи', 'autostory', 'кафе-столовая', 'чайхана у самвела', 'кафе', 'додо пицца', 'l cafe', 'правда кофе', 'донер кебаб', 'домашняя еда', 'пекарня24донер', '13 chef doner', 'оля', 'халяль', 'паназиатская кухня', 'восточная кухня', 'кафе-бар', 'крошка картошка', 'топор', 'ссср', 'столовая', 'бистро', 'кафе', 'i-chef бистро', 'accent', 'фуд-холл 2 быка', 'mfc foods', 'sushitop', 'кафе', 'свежая выпечка', 'monty cafe', 'шантимэль', 'кафе', 'кафе', 'белый лебедь', 'ваня', 'sushi case', 'киоск фастфудной продукции', 'family cafe mayak', 'стейки bar-b-que', 'дом плова', 'крошка картошка', 'ресторан', 'узбекские кафе', 'маракуйя', 'батон кофетон', 'кафе-хинкальная батоно', 'халяль', 'хлеба&зрелищ', 'сова', 'мята cyber', 'катька-запеканка', 'эскалоп', 'чайхана. uz', 'pro порции', 'теплое место', 'сундук', 'сады семирамиды', 'p3 coffee', 'чайхона №1', 'мск lounge', 'тануки', 'вistro 3.6', 'тануки', 'coffta', 'шаурма по-братски', 'семейный ресторан boobo', 'заказать шашлык на углях', 'самарканд', 'фалафель шеф', 'нуш-аппетит', 'мск lounge', 'жара', 'мосплов', 'плов центр', 'маргилан', 'coffee music', "coffeebar'17", 'узбекские блюда', 'эспрессо клуб', 'донер на пятерку', 'правый берег селигера', 'зарина', 'murloftik', 'кафе', 'корнер гриль', 'ne-polezno.ru', 'coffee bean', 'кардинал', 'персе кафе', 'i coffee', 'бохо лаундж', 'шир', 'бобс кофе', 'все лень', 'пончиковая', 'тануки', "coffeekaldi's", 'крендельок', 'eat&play', 'тандыр', 'chicko', 'pho bo ha noi', 'латарт', 'халяль', 'татнефть кафе', 'чойхона', 'чайхана халяль', 'халва', 'колибри', 'завод', 'едаки lunch', 'столовая', 'лав', 'пронто', 'b&b bradu bar', 'чайхана адияхан', 'буше', 'калина', 'monso', 'кофе to go', 'в своей тарелке', 'выпечка', 'остров', 'кафе', 'кафе пиццетория', 'энесай', 'халяль узбекские блюда', 'кулинария', 'фьюжн', 'золотая роща', 'чито-гврито', 'кафе-столовая', 'пармижано', 'капучино кидс', 'one price coffee', 'вах гоги', 'бульвар', 'старый город', 'кофе с собой', 'kitchen', 'буханка', 'шум города', 'ресторан вкусный хауз', 'бургер кинг', 'шашлык.рф', 'кафе-бар', 'мангалшашлык', 'khait food', "домино'с пицца", 'хлебопёкъ', 'доставка еды чайхона исфисор', 'чайная', 'one&double', 'марfино', 'amore grande', 'аладдин-системс', 'гастро бистро шаверма-братуха', '9 bar coffe', 'ям ям', 'теремок', 'чайхана манас', 'старое место', 'папа джонс', 'mio palermo', 'pitbull_cafe', 'grace pizza', "coffeekaldi's", 'doner one', "cousin's coffee", 'буфет', 'кофейня от автора', 'б12', 'кафе-бар суши-wolk', 'бестужев', 'lutom', 'пян-се', 'додо пицца', 'кофан', 'нуш донер', 'донер в пите', 'лепим и варим', 'грузинская кухня лело', 'додо пицца', 'шаурма', 'burger club', 'чайхана зам-зам', 'теремок', 'чайхана', 'шаурмкинг', 'bunker pub beer', 'coffee me', 'угар молодости', 'cofix', 'ля фантази', 'кафе', 'gourmet lunch', "домино'с пицца", 'bread пит', 'шаурма и лепёшка', 'чайхана дегунино', 'студия 2000', 'пицца на районе', 'кафе', 'бургер бокс', 'кафе', 'кафе', 'релти', 'шоколадница', 'cofefest', 'cofix', "coffeekaldi's", 'яндекс лавка', 'сушистор', 'крошка картошка', 'шоколадка', 'теремок', 'я люблю суши', 'есть, как есть', 'мекеним kg', 'два тандыра', 'кухня на район', "домино'с пицца", 'pizza hut', 'кафетериус № 6', 'пицца & гирос & шаурма', 'поле тëти анжелы', 'кафе', 'кафе', 'турецкая шаурма', 'маняма', 'кофе', 'sova coffee', 'кафе', 'кафе 69', "домино'с пицца", 'донер в пите', 'ресторан', 'чайхана исфисор', 'викрама', 'пекарня, кулинария', 'park point', 'клевер ритейл групп', 'кулинария виктория', 'лимонадница', 'арт меню', 'кафе', 'пекарня', 'буханка', 'ресторан', 'чебуречная история', 'пиво пицца', 'роса', 'al halal', 'уют', 'перекресток', 'vostok', 'ho cho pho', 'шаурма в пите', 'кафе', 'торты от сети кофеен шоколадница', 'kraskovka', 'кафе', 'нами', 'баррейро', 'кофе', 'донер24', 'пловная № 1', 'de bassus', 'self cafe', 'zerno', 'coffee itself', 'ели сацебели', 'сахар&сливки', 'ош', 'мск lounge', 'мама, я в тбилиси', 'чап-чак', 'джонджоли', 'ян примус', 'чайхана навои халяль', 'мимино', '8 пончиков', 'енисей', 'tidö-lindö', 'космос', 'оттепель', 'кебабушки.ру', 'у бабушки лётчика', 'домашний вкус', 'свадьба соек', 'андерсон на даче', 'дача', 'хинкальный дом', 'zамания', 'chou do', 'мимино', 'хинкальная легенда', 'хей мам', 'paul', 'арарат', 'московское небо', 'гастрономическая академия рожниковского', 'китчен', 'нейборс', 'кстати cafe at home', 'cafe & пельменная', 'базилик', 'панчетта', 'вареничная № 1', 'кофейня', 'гастрономическое пространство city food', 'proжарка', 'батони', 'славия', 'gagawa', 'грузинские традиции', 'шоколадница', 'теремок', 'cotto', 'coffee combo', 'додо пицца', 'bổ', 'жarka', 'bros burritos', 'хинкали gали', 'рыбацкая деревня', 'лавашок', 'ресторан пронто', 'кафе ласточка', "домино'с пицца", 'шашлычок', 'loo chi', 'островок суши', 'буханка', 'марина', 'vigor maker', 'восточный уют', 'джорджио и джорджия', 'ipho cafe', 'франклинс бургер', 'bbq point', 'очаг', 'krispy kreme', 'трэвэлерс кофе', 'koreana light', 'остерия трио', 'wild bean cafe', 'муза', 'чайхана', 'шашлычная-чебуречная', 'хо', "фоб'с", 'шоколадница', 'пиццадар', 'шантарам', 'пивной', 'буханка', 'bakery mart', 'shagdi', 'пекарня и кофейня', 'шаурма', 'mosweet', 'скала', 'домашняя столовая', 'базилик', 'чайхона лаззат', 'крошка картошка', 'фо бо 83', 'гедонист', 'локация', 'spot poke & bowls', 'чайхана долина', 'урожай', 'ребрышки и крылышки', 'буханка', ...]
df.isna().sum()
name 0 category 0 address 0 district 0 hours 535 lat 0 lng 0 rating 0 price 5088 avg_bill 4587 middle_avg_bill 5254 middle_coffee_cup 7868 chain 0 seats 3611 seats_category 3611 dtype: int64
pd.DataFrame(round(df.isna().mean()*100,)).style.background_gradient('coolwarm')
| 0 | |
|---|---|
| name | 0.000000 |
| category | 0.000000 |
| address | 0.000000 |
| district | 0.000000 |
| hours | 6.000000 |
| lat | 0.000000 |
| lng | 0.000000 |
| rating | 0.000000 |
| price | 61.000000 |
| avg_bill | 55.000000 |
| middle_avg_bill | 63.000000 |
| middle_coffee_cup | 94.000000 |
| chain | 0.000000 |
| seats | 43.000000 |
| seats_category | 43.000000 |
Много пропусков с столбцах hours, price, avg_bill, middle_avg_bill, middle_coffee_cup, seats. Пропуски в данном случае нельзя удалить, так как это может исказить данные.
#создаем столбец street с названиями улиц из столбцв с адресом
def extract_street(text):
return text.split(',')[1]
df['street'] = df['address'].apply(extract_street)
df
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | seats_category | street | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | wowфли | кафе | Москва, улица Дыбенко, 7/1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.878494 | 37.478860 | 5.0 | NaN | NaN | NaN | NaN | 0 | NaN | NaN | улица Дыбенко |
| 1 | четыре комнаты | ресторан | Москва, улица Дыбенко, 36, корп. 1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.875801 | 37.484479 | 4.5 | выше среднего | Средний счёт:1500–1600 ₽ | 1550.0 | NaN | 0 | 4.0 | Очень малые (1 - 25) | улица Дыбенко |
| 2 | хазри | кафе | Москва, Клязьминская улица, 15 | Северный административный округ | пн-чт 11:00–02:00; пт,сб 11:00–05:00; вс 11:00... | 55.889146 | 37.525901 | 4.6 | средние | Средний счёт:от 1000 ₽ | 1000.0 | NaN | 0 | 45.0 | Малые (26 - 50) | Клязьминская улица |
| 3 | dormouse coffee shop | кофейня | Москва, улица Маршала Федоренко, 12 | Северный административный округ | ежедневно, 09:00–22:00 | 55.881608 | 37.488860 | 5.0 | NaN | Цена чашки капучино:155–185 ₽ | NaN | 170.0 | 0 | NaN | NaN | улица Маршала Федоренко |
| 4 | иль марко | пиццерия | Москва, Правобережная улица, 1Б | Северный административный округ | ежедневно, 10:00–22:00 | 55.881166 | 37.449357 | 5.0 | средние | Средний счёт:400–600 ₽ | 500.0 | NaN | 1 | 148.0 | Крупные (101 - 250) | Правобережная улица |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8401 | суши мания | кафе | Москва, Профсоюзная улица, 56 | Юго-Западный административный округ | ежедневно, 09:00–02:00 | 55.670021 | 37.552480 | 4.4 | NaN | NaN | NaN | NaN | 0 | 86.0 | Средние (51 - 100) | Профсоюзная улица |
| 8402 | миславнес | кафе | Москва, Пролетарский проспект, 19, корп. 1 | Южный административный округ | ежедневно, 08:00–22:00 | 55.640875 | 37.656553 | 4.8 | NaN | NaN | NaN | NaN | 0 | 150.0 | Крупные (101 - 250) | Пролетарский проспект |
| 8403 | самовар | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648859 | 37.743219 | 3.9 | NaN | Средний счёт:от 150 ₽ | 150.0 | NaN | 0 | 150.0 | Крупные (101 - 250) | Люблинская улица |
| 8404 | чайхана sabr | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648849 | 37.743222 | 4.2 | NaN | NaN | NaN | NaN | 1 | 150.0 | Крупные (101 - 250) | Люблинская улица |
| 8405 | kebab time | кафе | Москва, Россошанский проезд, 6 | Южный административный округ | ежедневно, круглосуточно | 55.598229 | 37.604702 | 3.9 | NaN | NaN | NaN | NaN | 0 | 12.0 | Очень малые (1 - 25) | Россошанский проезд |
8403 rows × 16 columns
#создаем столбец is_24_7 для круглосуточных заведений
df['is_24_7'] = df['hours'] == 'ежедневно, круглосуточно'
df['is_24_7'].value_counts()
False 7673 True 730 Name: is_24_7, dtype: int64
df.head(5)
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | seats_category | street | is_24_7 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | wowфли | кафе | Москва, улица Дыбенко, 7/1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.878494 | 37.478860 | 5.0 | NaN | NaN | NaN | NaN | 0 | NaN | NaN | улица Дыбенко | False |
| 1 | четыре комнаты | ресторан | Москва, улица Дыбенко, 36, корп. 1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.875801 | 37.484479 | 4.5 | выше среднего | Средний счёт:1500–1600 ₽ | 1550.0 | NaN | 0 | 4.0 | Очень малые (1 - 25) | улица Дыбенко | False |
| 2 | хазри | кафе | Москва, Клязьминская улица, 15 | Северный административный округ | пн-чт 11:00–02:00; пт,сб 11:00–05:00; вс 11:00... | 55.889146 | 37.525901 | 4.6 | средние | Средний счёт:от 1000 ₽ | 1000.0 | NaN | 0 | 45.0 | Малые (26 - 50) | Клязьминская улица | False |
| 3 | dormouse coffee shop | кофейня | Москва, улица Маршала Федоренко, 12 | Северный административный округ | ежедневно, 09:00–22:00 | 55.881608 | 37.488860 | 5.0 | NaN | Цена чашки капучино:155–185 ₽ | NaN | 170.0 | 0 | NaN | NaN | улица Маршала Федоренко | False |
| 4 | иль марко | пиццерия | Москва, Правобережная улица, 1Б | Северный административный округ | ежедневно, 10:00–22:00 | 55.881166 | 37.449357 | 5.0 | средние | Средний счёт:400–600 ₽ | 500.0 | NaN | 1 | 148.0 | Крупные (101 - 250) | Правобережная улица | False |
Посмотрим на названия дубликатов, которые не являются сетевыми.
df[(df['name'].duplicated()) & (df['chain'] == 0)]['name'].unique()
array(['кафе', 'шаурма', 'ресторан', 'столовая', 'кафе-столовая',
'мск lounge', 'франклинс бургер', 'буфет', 'кофейня', 'бистро',
'новая столовая', 'важная персона', 'шаурма в пите', 'ля фантази',
'гастроферма', 'халва, сеть почтоматов', "домино'с пицца",
'korean chick', 'one&double', 'кофе стоп', 'шашлычная',
'pomodoro royal', 'пиццерия', 'здоровое питание', 'гриль хаус',
'carrots and beans', 'vabene', 'raw to go', 'istanbul kebab',
'шашлык хаус', 'ku: рамен изакая бар', 'hellopapaya',
'nova bubble tea', 'советские времена', 'хинкали point',
'старый город', 'il pizzaiolo', 'блины', 'pinzeria by bontempi',
'трапезная', 'рамен-клаб', 'хлеб насущный экспресс', 'на углях',
'папан', 'поминальные обеды', 'ням-ням', 'кофеin',
'pasta cup & pizza', 'домик в саду', 'wave california poke',
'кафе для поминок', 'новатор кофе', 'one price coffee', 'han cook',
'авлабар', 'bb grill', 'noba coffee', 'чудо тандыр', 'рэдимэйд',
'между булок', 'coffee point', 'семейная пекарня', 'чебуречная',
'кафе-кулинария', 'i like wine', 'вкусвилл, кафе', 'бишкек сити',
'чайхона ош сити', 'вьет лотос', 'burger club', 'кафе шашлык',
'чудо печка', 'токио рамен', 'донер бистро', 'ма ми',
'ели сацебели', 'espresso bar', 'хочу хычин', 'нэм нэм',
'pho street', 'донер & гриль', 'di villaggio', 'центр плова',
'шашлык на углях', 'гюмри хауз', 'чайхана бишкек сити',
'греки здесь', 'практика кофе'], dtype=object)
Заведения с названиями столовая, ресторани прочие, которые не являются сетевыми, стоит удалить из таблицы. Они могут исказить данные, особенно для выявления топ-15.
remove_from_df = [
'кафе', 'шаурма', 'ресторан', 'столовая', 'кафе-столовая', 'буфет',
'кофейня', 'бистро', 'шашлычная', 'пиццерия', 'блины', 'трапезная',
'поминальные обеды', 'кафе для поминок', 'чебуречная', 'кафе-кулинария',
'кафе шашлык'
]
df = df[~df['name'].isin(remove_from_df)].copy()
df
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | seats_category | street | is_24_7 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | wowфли | кафе | Москва, улица Дыбенко, 7/1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.878494 | 37.478860 | 5.0 | NaN | NaN | NaN | NaN | 0 | NaN | NaN | улица Дыбенко | False |
| 1 | четыре комнаты | ресторан | Москва, улица Дыбенко, 36, корп. 1 | Северный административный округ | ежедневно, 10:00–22:00 | 55.875801 | 37.484479 | 4.5 | выше среднего | Средний счёт:1500–1600 ₽ | 1550.0 | NaN | 0 | 4.0 | Очень малые (1 - 25) | улица Дыбенко | False |
| 2 | хазри | кафе | Москва, Клязьминская улица, 15 | Северный административный округ | пн-чт 11:00–02:00; пт,сб 11:00–05:00; вс 11:00... | 55.889146 | 37.525901 | 4.6 | средние | Средний счёт:от 1000 ₽ | 1000.0 | NaN | 0 | 45.0 | Малые (26 - 50) | Клязьминская улица | False |
| 3 | dormouse coffee shop | кофейня | Москва, улица Маршала Федоренко, 12 | Северный административный округ | ежедневно, 09:00–22:00 | 55.881608 | 37.488860 | 5.0 | NaN | Цена чашки капучино:155–185 ₽ | NaN | 170.0 | 0 | NaN | NaN | улица Маршала Федоренко | False |
| 4 | иль марко | пиццерия | Москва, Правобережная улица, 1Б | Северный административный округ | ежедневно, 10:00–22:00 | 55.881166 | 37.449357 | 5.0 | средние | Средний счёт:400–600 ₽ | 500.0 | NaN | 1 | 148.0 | Крупные (101 - 250) | Правобережная улица | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8401 | суши мания | кафе | Москва, Профсоюзная улица, 56 | Юго-Западный административный округ | ежедневно, 09:00–02:00 | 55.670021 | 37.552480 | 4.4 | NaN | NaN | NaN | NaN | 0 | 86.0 | Средние (51 - 100) | Профсоюзная улица | False |
| 8402 | миславнес | кафе | Москва, Пролетарский проспект, 19, корп. 1 | Южный административный округ | ежедневно, 08:00–22:00 | 55.640875 | 37.656553 | 4.8 | NaN | NaN | NaN | NaN | 0 | 150.0 | Крупные (101 - 250) | Пролетарский проспект | False |
| 8403 | самовар | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648859 | 37.743219 | 3.9 | NaN | Средний счёт:от 150 ₽ | 150.0 | NaN | 0 | 150.0 | Крупные (101 - 250) | Люблинская улица | True |
| 8404 | чайхана sabr | кафе | Москва, Люблинская улица, 112А, стр. 1 | Юго-Восточный административный округ | ежедневно, круглосуточно | 55.648849 | 37.743222 | 4.2 | NaN | NaN | NaN | NaN | 1 | 150.0 | Крупные (101 - 250) | Люблинская улица | True |
| 8405 | kebab time | кафе | Москва, Россошанский проезд, 6 | Южный административный округ | ежедневно, круглосуточно | 55.598229 | 37.604702 | 3.9 | NaN | NaN | NaN | NaN | 0 | 12.0 | Очень малые (1 - 25) | Россошанский проезд | True |
8034 rows × 17 columns
Категории заведений
Посмотрим, какие категории заведений представлены в данных. Исследуем количество объектов общественного питания по категориям. Построим визуализации.
df.groupby('name') \
.agg(count=('name', 'count')) \
.sort_values(by='count', ascending=False) \
.reset_index() \
.head(10) \
.style.background_gradient('coolwarm')
| name | count | |
|---|---|---|
| 0 | шоколадница | 120 |
| 1 | домино'с пицца | 77 |
| 2 | додо пицца | 74 |
| 3 | one price coffee | 72 |
| 4 | яндекс лавка | 69 |
| 5 | cofix | 65 |
| 6 | prime | 50 |
| 7 | хинкальная | 44 |
| 8 | кофепорт | 42 |
| 9 | кулинарная лавка братьев караваевых | 39 |
df.query('(name == "кафе" or name == "ресторан" or name == "столовая") and chain == 1')
| name | category | address | district | hours | lat | lng | rating | price | avg_bill | middle_avg_bill | middle_coffee_cup | chain | seats | seats_category | street | is_24_7 |
|---|
categories = df.groupby('category')['name'].count().reset_index(name='count').sort_values(by='count', ascending=True)
categories
| category | count | |
|---|---|---|
| 1 | булочная | 253 |
| 7 | столовая | 274 |
| 2 | быстрое питание | 558 |
| 5 | пиццерия | 629 |
| 0 | бар,паб | 760 |
| 4 | кофейня | 1398 |
| 6 | ресторан | 1998 |
| 3 | кафе | 2164 |
categories['count'].sum()
8034
fig = px.bar(categories,
x = 'count',
y='category',
title='Распределение заведений по категориям',
template='plotly_white')
fig.update_layout(xaxis_title='Количество',
yaxis_title='Категория')
fig.show()
Комметарий:
Всего 8 категорий. Топ-3:
кафе: 2376 заведений. рестораны - 2042. Кофейня на третьем - 1413.Первые три категории составляют 69% от общего числа заведений.
Наименее популярная категория - cтоловые и булочные. Они составляют 6% от общего числа заведений.
Кафе и ресторан являются местом для долгих посиделок, деловых и дружеских встреч, семейных праздников. Они рассчитаны на широкую аудиторию с разнообразным меню и кухней. Могут располагаться почти везде: рядом с деловыми центрами, городскими парками, в спальном районе. Особой популярностью пользуются бизнес-ланчи и завтраки в кафе.
Кофейни сегодня пользуются довольно хорошим спросом в связи с ритмом жизни людей. Сюда заходят ненадолго и чаще всего берут на вынос. Подходят для недолгих встреч, быстрых обедов с кофе, но меню содержит ограниченное количество блюд - в основном, это выпечка и десерты.
Бары (764) пользуются спросом у молодежи и людей средних лет. Актуально для встреч коллег после рабочего дня, для встречи с друзьями.
Пиццерия (633) обладает ограниченным ассортиментом и работает на доставку.
Быстрое питание (603) обычно находятся в торговых центрах, бизнес-центрах, где люди питаются между делами.
Столовые (315) обычно располагаются рядом с университетами, школами, государственными учреждениями, где есть большой поток людей.
Булочные (256) на на последнем месте(256 заведений). Подходит для быстрого перекуса или покупкой выпечки после рабочего дня.
Количество посадочных мест по категориям
# возьмем медианное количество посадочных мест
seats_category = df.groupby('category')['seats'].median().reset_index(name='count').sort_values(by='count', ascending=False)
seats_category
| category | count | |
|---|---|---|
| 6 | ресторан | 86.0 |
| 0 | бар,паб | 83.0 |
| 4 | кофейня | 80.0 |
| 7 | столовая | 80.0 |
| 2 | быстрое питание | 65.0 |
| 3 | кафе | 60.0 |
| 5 | пиццерия | 55.0 |
| 1 | булочная | 50.0 |
fig = px.bar(seats_category,
x='category',
y='count',
title='Количество посадочных мест по категориям',
template='plotly_white',
color='category'
)
fig.update_layout(
yaxis_title='Количество посадочных мест',
xaxis_title='Категория заведения',
xaxis_tickangle=-45,
showlegend=False
)
fig.show()
ресторанов, баров и кофеен.Соотношение сетевых и несетевых заведений
chain_counts = df['chain'].value_counts()
chain_counts
0 4833 1 3201 Name: chain, dtype: int64
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
plt.pie(chain_counts,
labels=['Несетевые', 'Сетевые'],
autopct='%1.1f%%',
colors=['orange','skyblue'],
startangle=90)
plt.title('Соотношение типов заведений')
plt.subplot(1, 2, 2)
chain_counts.plot(kind='bar', color=['orange','skyblue'])
plt.xticks([0, 1], ['Несетевые', 'Сетевые'], rotation=0)
plt.title('Количество заведений')
plt.ylabel('Количество')
plt.tight_layout()
plt.show()
Какие категории заведений чаще являются сетевыми?
# Создаем перекрестную таблицу
chain_category = pd.crosstab(df['category'], df['chain'])
chain_category.columns = ['Несетевое', 'Сетевое']
chain_category
| Несетевое | Сетевое | |
|---|---|---|
| category | ||
| бар,паб | 592 | 168 |
| булочная | 96 | 157 |
| быстрое питание | 326 | 232 |
| кафе | 1386 | 778 |
| кофейня | 678 | 720 |
| пиццерия | 299 | 330 |
| ресторан | 1269 | 729 |
| столовая | 187 | 87 |
chain_melted = chain_category.reset_index().melt(
id_vars='category',
value_vars=['Несетевое', 'Сетевое'],
var_name='Тип заведения',
value_name='Количество'
)
chain_melted
| category | Тип заведения | Количество | |
|---|---|---|---|
| 0 | бар,паб | Несетевое | 592 |
| 1 | булочная | Несетевое | 96 |
| 2 | быстрое питание | Несетевое | 326 |
| 3 | кафе | Несетевое | 1386 |
| 4 | кофейня | Несетевое | 678 |
| 5 | пиццерия | Несетевое | 299 |
| 6 | ресторан | Несетевое | 1269 |
| 7 | столовая | Несетевое | 187 |
| 8 | бар,паб | Сетевое | 168 |
| 9 | булочная | Сетевое | 157 |
| 10 | быстрое питание | Сетевое | 232 |
| 11 | кафе | Сетевое | 778 |
| 12 | кофейня | Сетевое | 720 |
| 13 | пиццерия | Сетевое | 330 |
| 14 | ресторан | Сетевое | 729 |
| 15 | столовая | Сетевое | 87 |
total_counts = chain_melted.groupby('category')['Количество'].transform('sum')
chain_melted['Процент'] = chain_melted['Количество'] / total_counts * 100
chain_melted
| category | Тип заведения | Количество | Процент | |
|---|---|---|---|---|
| 0 | бар,паб | Несетевое | 592 | 77.894737 |
| 1 | булочная | Несетевое | 96 | 37.944664 |
| 2 | быстрое питание | Несетевое | 326 | 58.422939 |
| 3 | кафе | Несетевое | 1386 | 64.048059 |
| 4 | кофейня | Несетевое | 678 | 48.497854 |
| 5 | пиццерия | Несетевое | 299 | 47.535771 |
| 6 | ресторан | Несетевое | 1269 | 63.513514 |
| 7 | столовая | Несетевое | 187 | 68.248175 |
| 8 | бар,паб | Сетевое | 168 | 22.105263 |
| 9 | булочная | Сетевое | 157 | 62.055336 |
| 10 | быстрое питание | Сетевое | 232 | 41.577061 |
| 11 | кафе | Сетевое | 778 | 35.951941 |
| 12 | кофейня | Сетевое | 720 | 51.502146 |
| 13 | пиццерия | Сетевое | 330 | 52.464229 |
| 14 | ресторан | Сетевое | 729 | 36.486486 |
| 15 | столовая | Сетевое | 87 | 31.751825 |
fig = px.bar(
chain_melted,
x='category',
y='Количество',
color='Тип заведения',
title='Распределение сетевых и несетевых заведений по категориям',
labels={'category': 'Категория заведения'},
template='plotly_white',
text=chain_melted['Процент'].apply(lambda x: f'{x:.1f}%'))
fig.update_layout(
xaxis_tickangle=-45,
xaxis={'categoryorder':'total descending'}
)
fig.show()
кофейня (51%), пиццерия (52.1%) и булочная (61.3%) сетевых заведений чуть больше, чем несетевых, что отличает эти категории от остальных. Возможно, причинами этого являются готовый бизнес с минимальными вложениями, довольно простая организация и управление по сравнению с другими категориями (кофе, готовая выпечка, единый рецепт пиццы). Также люди, возможно, люди охотнее идут в сетевые заведения данной категории из-за доверия к компании.бар, паб(78%), так же столовая(72.1%), что вполне обоснованно, так как бары чаще всего имеют свой уникальный стиль и неповторимую атмосферу, чтобы повышать лояльность, степень комфорта посетителей. А столовые ориентируются на локальный опыт и быстрое питание, однако столовые тоже должны выделяться среди остальных и иметь свою изюминку.Топ-15 популярных сетей в Москве
top_15 = (
df[df['chain'] == 1]
['name']
.value_counts()
.head(15)
.reset_index()
)
top_15.columns = ['name', 'count']
top_15
| name | count | |
|---|---|---|
| 0 | шоколадница | 120 |
| 1 | домино'с пицца | 76 |
| 2 | додо пицца | 74 |
| 3 | one price coffee | 71 |
| 4 | яндекс лавка | 69 |
| 5 | cofix | 65 |
| 6 | prime | 50 |
| 7 | хинкальная | 44 |
| 8 | кофепорт | 42 |
| 9 | кулинарная лавка братьев караваевых | 39 |
| 10 | теремок | 38 |
| 11 | чайхана | 37 |
| 12 | буханка | 32 |
| 13 | cofefest | 32 |
| 14 | му-му | 27 |
fig = px.bar(
top_15,
x='name',
y='count',
title='Топ-15 популярных сетей в Москве',
labels={'name':'Название заведения', 'count':'Количество'},
template='plotly_white',
color='name'
)
fig.update_layout(
yaxis_title='Количество заведений в сети',
xaxis_title='Название сети',
xaxis_tickangle=-45,
showlegend=False
)
fig.show()
Шоколадница составляет 14% от количества всех сетей из топ-15 (120).Общий признак, который объединяет эти сети - шаговая доступность от общественного транспорта (метро, автобусы) и расположение в районе с большим потоком людей. Также стоит отметить предельный уровень среднего чека, что благоприятно влияет на покупательную способность населения (предсказуемость цен при посещении, что облегчает выбор для людей). Часто люди выбирают знакомые места в незнакомых местах.
df_chain = df[df['chain'] == 1]
top_15 = df_chain.groupby('name').agg({'rating' : 'median', 'category' : pd.Series.mode, 'district' : 'count'})
top_15 = top_15.rename(columns={'district':'count'})
top_15 = top_15.sort_values('count', ascending = False).reset_index().head(15)
top_15
| name | rating | category | count | |
|---|---|---|---|---|
| 0 | шоколадница | 4.20 | кофейня | 120 |
| 1 | домино'с пицца | 4.20 | пиццерия | 76 |
| 2 | додо пицца | 4.30 | пиццерия | 74 |
| 3 | one price coffee | 4.20 | кофейня | 71 |
| 4 | яндекс лавка | 4.00 | ресторан | 69 |
| 5 | cofix | 4.10 | кофейня | 65 |
| 6 | prime | 4.20 | ресторан | 50 |
| 7 | хинкальная | 4.40 | кафе | 44 |
| 8 | кофепорт | 4.20 | кофейня | 42 |
| 9 | кулинарная лавка братьев караваевых | 4.40 | кафе | 39 |
| 10 | теремок | 4.10 | ресторан | 38 |
| 11 | чайхана | 4.10 | кафе | 37 |
| 12 | cofefest | 4.05 | кофейня | 32 |
| 13 | буханка | 4.40 | булочная | 32 |
| 14 | му-му | 4.30 | кафе | 27 |
top15_category = top_15.groupby('category')['count'].sum().reset_index()
fig = px.bar(
top15_category,
x='category',
y='count',
title='Распределение топ-15 сетей по типам заведений',
labels={'category': 'Тип заведения', 'count': 'Количество объектов'},
color='category',
template='plotly_white'
)
fig.update_layout(
xaxis_tickangle=-45,
yaxis_title='Количество заведений',
showlegend=False,
xaxis={'categoryorder': 'total descending'}
)
fig.show()
Комментарий:
кофейня - самый популярный тип заведения из Топ-15 (330 кофеен)Ресторан, пиццерия, кафе ненамного - 147-157 заведений.Булочная на последнем месте - 32.Кофейни популярны, потому что сочетают в себе функциональность (кофе + еда + работа). К тому же особая атмосфера, любовь к кофе и привычка создавать себе ритуал делают кофейни более востребованными в обществе.
Административные районы Москвы. Общее количество заведений и количество заведений каждой категории по районам.
district_count = df['district'].value_counts().reset_index()
district_count.columns = ['district', 'total_count']
district_count
| district | total_count | |
|---|---|---|
| 0 | Центральный административный округ | 2213 |
| 1 | Северный административный округ | 856 |
| 2 | Южный административный округ | 854 |
| 3 | Северо-Восточный административный округ | 847 |
| 4 | Западный административный округ | 807 |
| 5 | Восточный административный округ | 741 |
| 6 | Юго-Западный административный округ | 676 |
| 7 | Юго-Восточный административный округ | 664 |
| 8 | Северо-Западный административный округ | 376 |
district_chain_df = df.groupby(['district', 'category']).agg({'rating' : 'median', 'name' : 'count'})
district_chain_df = district_chain_df.sort_values('rating', ascending = False).reset_index()
district_chain_df = district_chain_df.rename(columns={'name':'count'})
district_chain_df.head()
| district | category | rating | count | |
|---|---|---|---|---|
| 0 | Центральный административный округ | бар,паб | 4.5 | 363 |
| 1 | Западный административный округ | бар,паб | 4.5 | 50 |
| 2 | Северо-Западный административный округ | бар,паб | 4.4 | 23 |
| 3 | Центральный административный округ | ресторан | 4.4 | 666 |
| 4 | Центральный административный округ | пиццерия | 4.4 | 111 |
fig = px.bar(district_chain_df,
x='count',
y='district',
template='plotly_white',
color='category'
)
fig.update_layout(title='Количество заведений каждой категории по районам',
xaxis_title='Количество заведений',
yaxis_title='Название района',
yaxis={'categoryorder':'total ascending'}
)
fig.show()
2242. 890-898.850.709-798.409.В центральном административном округе сосредоточены офисы, туристические достопримечательности, бизнес-центры. Значит, там большая проходимость. Развитая инфраструктура так же играет ключевую роль: общественный транспорт, удобные пешеходные переходы, развлекательные объекты. Здесь высокая конкуренция, но разнообразие заведений только привлекает поток посетителей. Оплата аренды выше, но есть большая вероятность окупиться.
Распределение средних рейтингов по категориям заведений
avg_rating_category = round(df.groupby('category')['rating'].mean().reset_index(), 2).sort_values(by='rating', ascending=False)
avg_rating_category
| category | rating | |
|---|---|---|
| 0 | бар,паб | 4.39 |
| 5 | пиццерия | 4.30 |
| 6 | ресторан | 4.29 |
| 4 | кофейня | 4.28 |
| 1 | булочная | 4.27 |
| 7 | столовая | 4.21 |
| 3 | кафе | 4.15 |
| 2 | быстрое питание | 4.06 |
fig = px.bar(
avg_rating_category,
x='category',
y='rating',
color ='category',
title='Средний рейтинг по категориям заведений',
labels={'category':'Категория заведения', 'rating':'Рейтинг'},
template='plotly_white'
)
fig.update_layout(
xaxis_tickangle=-45,
yaxis_range=[avg_rating_category['rating'].min() - 0.2,
avg_rating_category['rating'].max() + 0.2],
showlegend = False
)
fig.show()
Бары имеют лучший средний рейтинг среди заведений Москвы (4.39). Возможно, развлекательные заведения оставляют чаще остальных оставляют хорошее впечатление. Напитки в барах создаются топовыми барменами, они обучаются в лучших школах. Высокий рейтинг - это результат комплексного подхода и создание уникального опыта.Пиццерия на втором месте. Причины могут быть разные, но, предположительно, про хорошую пиццерию люди должны знать, поэтому посетители чаще оставляют отзывы и ставят рейтинги. Пиццерия ориентируется на одном блюде, и важно, чтобы людям действительно нравилось и им хотелось заказать пиццу в проверенном месте на все случаи жизни за приемлемую стоимость.Быстрое питание имеет наименьший рейтинг из топа. Возможные причины: люди едят на ходу, покупают и разочаровываются. Может быть дело в качестве продуктов, проблемы с обслуживанием, антисанитария и пр.Фоновая картограмма (хороплет) со средним рейтингом заведений каждого района
rating_df = df.groupby('district', as_index=False)['rating'].agg('mean').round(2)
rating_df
| district | rating | |
|---|---|---|
| 0 | Восточный административный округ | 4.19 |
| 1 | Западный административный округ | 4.19 |
| 2 | Северный административный округ | 4.25 |
| 3 | Северо-Восточный административный округ | 4.16 |
| 4 | Северо-Западный административный округ | 4.23 |
| 5 | Центральный административный округ | 4.38 |
| 6 | Юго-Восточный административный округ | 4.12 |
| 7 | Юго-Западный административный округ | 4.19 |
| 8 | Южный административный округ | 4.19 |
rating_df = df.groupby('district', as_index=False)['rating'].agg('mean').round(2)
rating_df
with open('/datasets/admin_level_geomap.geojson', 'r') as f:
geo_json = json.load(f)
state_geo = '/datasets/admin_level_geomap.geojson'
moscow_lat, moscow_lng = 55.751244, 37.618423
m = Map(location=[moscow_lat, moscow_lng], zoom_start=10, tiles='Cartodb Positron')
Choropleth(
geo_data=state_geo,
data=rating_df,
columns=['district', 'rating'],
key_on='feature.name',
fill_color='YlOrRd',
fill_opacity=0.8,
legend_name='Средний рейтинг заведений по районам',
).add_to(m)
m
В ЦАО за рейтинг самый высокий - 4.38.
Заведения датасета на карте
m = folium.Map([55.751244, 37.618423], zoom_start=8)
heatmap = df[['lat','lng']]
m.add_child(plugins.HeatMap(heatmap, radius=14))
m
marker_cluster = MarkerCluster().add_to(m)
def create_clusters(row):
Marker(
[row['lat'], row['lng']],
popup=f"{row['name']} {row['rating']}",
).add_to(marker_cluster)
df.apply(create_clusters, axis=1)
m
По карте наглядно видно, что больше всего заведений в центре Москвы, т.е. в ЦАО.
Топ-15 улиц по количеству заведений
top_streets = df.groupby('street').agg(count=('name', 'count')).sort_values(
'count', ascending=False).head(15).index.tolist()
street_cat = df[df['street'].isin(top_streets)].groupby(['street', 'category'], as_index=False).agg(
count=('street', 'count')).sort_values('count', ascending=False)
street_cat
| street | category | count | |
|---|---|---|---|
| 92 | проспект Мира | кафе | 52 |
| 95 | проспект Мира | ресторан | 44 |
| 62 | МКАД | кафе | 36 |
| 93 | проспект Мира | кофейня | 35 |
| 87 | проспект Вернадского | ресторан | 33 |
| ... | ... | ... | ... |
| 88 | проспект Вернадского | столовая | 1 |
| 82 | проспект Вернадского | булочная | 1 |
| 58 | Люблинская улица | пиццерия | 1 |
| 65 | МКАД | столовая | 1 |
| 55 | Люблинская улица | быстрое питание | 1 |
110 rows × 3 columns
fig = px.bar(
street_cat,
x='count',
y='street',
color ='category',
title='Топ-15 улиц по количеству заведений и их категории',
labels={'category':'Категория', 'count':'Количество заведений'},
template='plotly_white'
)
fig.update_layout(
xaxis_title='Количество заведений',
yaxis_title='Название улиц',
yaxis={'categoryorder':'total ascending'},
xaxis_tickangle=-45
)
fig.show()
Комментарий:
проспекте мира. кафе, рестораны и кофейни.Профсоюзная, Ленинградский и проспекте Вернадского больше 100 заведений. Проспект Мира является одной из главных радиальных проспектов Москвы, здесь состредоточены исторические достопримечательноси, важные траспортные узлы, развитая инфраструктура, престижный уровень жизни. Соединяет ключевые районы: Центр, Алексеевский, Ростокино, ВДНХ, Останкино. Вполне логично, что проспект Мира на первом месте.
Почти то же самое можно сказать и о других популярных улицах - это крупные траспортные магистрали Москвы. Эти улицы соединяют разные части города и влияют на логистику города и жизнь миллионов людей.
Улицы, на которых находится только один объект общепита.
single_object = df['street'].value_counts().reset_index()
single_object.columns = ['street_name', 'cafe_count']
single_object = single_object[single_object['cafe_count'] == 1]
single_object
| street_name | cafe_count | |
|---|---|---|
| 957 | парк Алтуфьево | 1 |
| 958 | № 7 | 1 |
| 959 | проспект Лихачёва | 1 |
| 960 | улица Габричевского | 1 |
| 961 | улица Вешних Вод | 1 |
| ... | ... | ... |
| 1407 | Маленковская улица | 1 |
| 1408 | 2-я Рощинская улица | 1 |
| 1409 | Симферопольский проезд | 1 |
| 1410 | улица Луиджи Лонго | 1 |
| 1411 | 4-й Воробьёвский проезд | 1 |
455 rows × 2 columns
single_objects = df[df['street'].isin(single_object['street_name'])]
district_category_counts = (single_objects
.groupby(['district', 'category'], as_index=False)
.size()
.rename(columns={0: 'count'}))
# Сортируем округа по общему количеству одиночных заведений
district_order = single_objects['district'].value_counts().index
district_category_counts['district'] = pd.Categorical(district_category_counts['district'],
categories=district_order,
ordered=True)
fig = px.bar(
district_category_counts,
x='size',
y='district',
color='category',
title='Распределение одиночных заведений по округам и категориям',
labels={'size': 'Количество заведений', 'district': 'Округ'},
height=600,
template='plotly_white'
)
fig.update_layout(
xaxis_title='Количество заведений',
yaxis_title='Округ',
legend_title='Категория',
yaxis={'categoryorder': 'total ascending'})
fig.show()
Комментарий:
кафе, ресторан и кофейня.кафе, кроме СЗАО.В общем, ЦАО по количеству заведений лидирует, поэтому среди одиночных заведений стоит на первом месте.
Возможные причины, почему на некоторых улицах Москвы может быть только по одному заведению:
avg_bill = df.groupby('district', as_index=False).agg(
avg_bill=('middle_avg_bill', 'mean'))
avg_bill['avg_bill'] = round(avg_bill['avg_bill'], 2)
avg_bill
| district | avg_bill | |
|---|---|---|
| 0 | Восточный административный округ | 830.33 |
| 1 | Западный административный округ | 1056.27 |
| 2 | Северный административный округ | 936.25 |
| 3 | Северо-Восточный административный округ | 719.57 |
| 4 | Северо-Западный административный округ | 822.69 |
| 5 | Центральный административный округ | 1192.72 |
| 6 | Юго-Восточный административный округ | 658.93 |
| 7 | Юго-Западный административный округ | 796.81 |
| 8 | Южный административный округ | 730.48 |
state_geo = '/datasets/admin_level_geomap.geojson'
moscow_lat, moscow_lng = 55.751244, 37.618423
m = Map(location=[moscow_lat, moscow_lng], zoom_start=10)
Choropleth(
geo_data=state_geo,
data=avg_bill,
columns=['district', 'avg_bill'],
key_on='feature.name',
fill_color='YlOrRd',
fill_opacity=0.8,
legend_name='Медианная стоимость среднего чека по районам',
).add_to(m)
m
Отдаленность от центра довольно сильно влияет на ценовой диапазон (примерно на 1.5-2 раза).
Выводы:
кафе: 2376 заведений. На втором месте рестораны - 2042. Кофейня на третьем - 1413.Быстрое питание имеет наименьший рейтинг из топа.455 улиц, где только 1 заведение. Чаще всего это кафе.Количество кофеен и их расположение
coffee_count = df[df['category'] == 'кофейня']
print(f"Всего кофеен в датасете: {coffee_count.shape[0]}")
Всего кофеен в датасете: 1398
coffee_by_district = df[df['category'] == 'кофейня'].groupby('district', as_index=False) \
.size() \
.sort_values('size', ascending=False)
print("Районы с наибольшим количеством кофеен:")
print(coffee_by_district.reset_index())
Районы с наибольшим количеством кофеен: index district size 0 5 Центральный административный округ 426 1 2 Северный административный округ 191 2 3 Северо-Восточный административный округ 156 3 1 Западный административный округ 147 4 8 Южный административный округ 129 5 0 Восточный административный округ 105 6 7 Юго-Западный административный округ 95 7 6 Юго-Восточный административный округ 88 8 4 Северо-Западный административный округ 61
# создаём карту Москвы
m3 = Map(location=[moscow_lat, moscow_lng], zoom_start=10)
# создаём пустой кластер, добавляем его на карту
marker_cluster = MarkerCluster().add_to(m3)
# пишем функцию, которая принимает строку датафрейма,
# создаёт маркер в текущей точке и добавляет его в кластер marker_cluster
def create_clusters(row):
Marker(
[row['lat'], row['lng']],
popup=f"{row['name']} {row['rating']}",
).add_to(marker_cluster)
# применяем функцию create_clusters() к каждой строке датафрейма
coffee_count.apply(create_clusters, axis=1)
# выводим карту
m3
Комментарий: В центре ожидаемо много кофеен, большая концентрация и максимальный трафик наблюдается в основном:
Набрали популярность в последние годы скрытые кофейни, которые располагаются во дворах, создавая особу атмосферу для посетителей. Возможно, стоит обратить внимание на такой формат.
Центр привлекателен высокой проходимость и особенностей потребительского поведения: большинство берут кофе на вынос или сидят в кофейнях, создавая себе место для работы.
Круглосуточные кофейни
day_n_night = df.query('hours == "ежедневно, круглосуточно" and category == "кофейня"')
coffee_shops = day_n_night.groupby('district').agg(count=('name', 'count')).reset_index()
print(f'Количество круглосуточных кофеен: {coffee_shops["count"].sum()}')
Количество круглосуточных кофеен: 59
fig = px.bar(
data_frame=coffee_shops.sort_values('count', ascending=False),
x='count', y='district',
title='Количество круглосуточных кофеен по районам',
height=450
)
fig.update_layout(
legend_title='Район',
template='plotly_white',
xaxis_title='Количество заведений',
yaxis_title='Название района',
xaxis_tickangle=-45,
yaxis={'categoryorder':'total ascending'}
)
fig.show()
Круглосуточных кофеен больше всего в ЦАО, но количество довольно мало - 26.
cafe_rating_cost = df.groupby(by='district', as_index=False).agg(
count=('rating', 'mean'), avg_cup=('middle_coffee_cup', 'mean'))
cafe_rating_cost['count'] = round(cafe_rating_cost['count'], 2)
cafe_rating_cost['avg_cup'] = round(cafe_rating_cost['avg_cup'])
cafe_rating_cost.sort_values('avg_cup', ascending=False)
| district | count | avg_cup | |
|---|---|---|---|
| 1 | Западный административный округ | 4.19 | 190.0 |
| 5 | Центральный административный округ | 4.38 | 188.0 |
| 7 | Юго-Западный административный округ | 4.19 | 183.0 |
| 0 | Восточный административный округ | 4.19 | 174.0 |
| 2 | Северный административный округ | 4.25 | 165.0 |
| 3 | Северо-Восточный административный округ | 4.16 | 165.0 |
| 4 | Северо-Западный административный округ | 4.23 | 160.0 |
| 8 | Южный административный округ | 4.19 | 158.0 |
| 6 | Юго-Восточный административный округ | 4.12 | 151.0 |
fig_rating = px.bar(
cafe_rating_cost,
x='count',
y='district',
title='Средний рейтинг кофеен по округам Москвы',
labels={'count': 'Средний рейтинг', 'district': 'Округ'},
color='count',
color_continuous_scale='Blues',
text='count'
)
fig_rating.update_layout(
yaxis={'categoryorder': 'total ascending'},
xaxis_range=[0, 5],
coloraxis_showscale=False
)
fig_rating.update_traces(texttemplate='%{text:.2f}', textposition='outside')
fig_rating.show()
Заведения вынуждены поддерживать высокие стандарты и тщательнее следят за отзывами. Посетители чаще оставляют отзывы в центре и ценовая политика выше, чем в других районах. Также , возможно, в центре чаще проводятся проверки качества соответствующими органами. Комплексный подход заведений благоприятно влияют на рейтинги.
fig_price = px.bar(
cafe_rating_cost,
x='avg_cup',
y='district',
title='Средняя цена кофе по округам Москвы',
labels={'avg_cup': 'Средняя цена (руб)', 'district': 'Округ'},
color='avg_cup',
color_continuous_scale='Reds',
text='avg_cup'
)
fig_price.update_layout(
yaxis={'categoryorder': 'total ascending'},
coloraxis_showscale=False
)
fig_price.update_traces(texttemplate='%{text} руб', textposition='outside')
fig_price.show()
Это возможный показатель перспективности Западной административной области. Конкуренция чуть ниже, чем в ЦАО, лояльная аренда, растущий спрос.
190 рублей. 188 и ЮЗАО 183.Центральный административный округ показывает наилучший рейтинг среди остальных.Северо-Западном административном округе. Кофейни тщательно следят за отзывами и рейтингами.